package test.ted.com.androidplugin2

import android.content.Context
import android.content.pm.PackageManager
import android.os.Handler
import android.os.Looper
import android.os.Message
import android.util.Log
import cn.ted.pluginlib.contract.*
import dalvik.system.PathClassLoader
import org.json.JSONObject


/**
 * Created by sfshine on 18-6-5.
 */
const val PLUGIN_PKG_NAME = "cn.ted.sdkplugin"
const val TEST_CLASS_NAME = "cn.ted.sdkplugin.TestPluginImpl"
const val PLUGIN_CLASS_NAME = "cn.ted.sdkplugin.PluginManager"
const val TAG = "HostManager"

class HostManager : IHostInterface {
    lateinit var mContext: Context
    var mPluginManager: IPluginInterface? = null
    lateinit var mHostHandler: HostHandler

    override fun init(context: Context, str: String) {
        Log.d(TAG, "init start")
        mContext = context
        mHostHandler = HostHandler(Looper.getMainLooper())
        mPluginManager = createPluginInstance(context, PLUGIN_PKG_NAME, PLUGIN_CLASS_NAME)
        mPluginManager?.init(context, str)
        mPluginManager?.registerHandler(mHostHandler, FLAG_MSG_ITEM)
        var data = JSONObject()
        data.put("key", str)
        mPluginManager?.sendMessage(data, mHostHandler, 8888)
        mPluginManager?.unRegisterHandler(mHostHandler, FLAG_MSG_ITEM)
        Log.d(TAG, "init end")
    }

    override fun getComInfoProcessor(): IComInfoProcessor {
        TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
    }

    override fun registerHandler(handler: IMessageHandler, flag: Int) {
        TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
    }

    override fun unRegisterHandler(handler: IMessageHandler, flag: Int) {
        TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
    }

    override fun sendMessage(data: JSONObject, handler: IMessageHandler, msgid: Int) {
        TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
    }


    fun getTestPlugin(context: Context): ITestPlugin? {
        return createPluginInstance(context, PLUGIN_PKG_NAME, TEST_CLASS_NAME)
    }

    /**
     *创建类加载器，把dex加载到虚拟机中
     *第一个参数：是指定apk安装的路径，这个路径要注意只能是通过actInfo.applicationInfo.sourceDir来获取
     *第二个参数：是C/C++依赖的本地库文件目录,可以为null
     *第三个参数：是上一级的类加载器*
     */
    private inline fun <T> createPluginInstance(context: Context, pkgName: String, className: String): T? {
        var dynamic: Class<*>
        /** 使用PathClassLoader方法加载类  */
        val apps = context.packageManager.getInstalledApplications(PackageManager.MATCH_UNINSTALLED_PACKAGES)
        // 获得指定包名的applicationInfo的信息
        try {
            val applicationInfo = apps.first { it.packageName == pkgName }
            val sourceDir = applicationInfo.sourceDir
            val libPath = applicationInfo.nativeLibraryDir
            println("sourceDir: $sourceDir")
            println("libPath: $libPath")
            val pcl = PathClassLoader(sourceDir, libPath, context.classLoader)
            dynamic = pcl.loadClass(className)
            return dynamic.newInstance() as T
        } catch (e: NoSuchElementException) {
            Log.w(TAG, Log.getStackTraceString(e))
        } catch (e: ClassNotFoundException) {
            Log.w(TAG, Log.getStackTraceString(e))
        }
        return null
    }

    class HostHandler(mainLooper: Looper?) : Handler(mainLooper), IMessageHandler {
        override fun handleMessage(jsonObject: JSONObject) {
            Log.d(TAG, "HostHandler: will handle message from plugin $jsonObject")
            var message = Message.obtain()
            message.obj = jsonObject
            message.what = 8888
            sendMessage(message)
        }

        override fun handleMessage(msg: Message?) {
            Log.d(TAG, "HostHandler: will handle message in UI Thread ${msg?.obj}")

        }
    }
}